package com.xyd.auth.security.filter;

import com.alibaba.fastjson.JSON;
import com.xyd.common.result.GlobalResultClass;
import com.xyd.common.result.ResultStatusEnum;
import com.xyd.common.util.JwtHelper;
import com.xyd.common.util.ResponseUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.*;

@Slf4j
public class TokenAuthenticationFilter extends OncePerRequestFilter {
    // 注入redis，不需要使用@Autowired
    private RedisTemplate redisTemplate;

    public TokenAuthenticationFilter(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    //如果是登录接口，直接放行 不需要做认证判定
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //如果是登录接口，直接放行 不需要做认证判定
        if("/admin/system/index/login".equals(request.getRequestURI())){
            filterChain.doFilter(request,response);// 放行
            return;
        }
        log.info("进入到TokenAuthenticationFilter,{}",request.getHeader("token"));
        // 如果不是登录接口，得到当前用户认证对象
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
        if(null != authentication){ // 认证当前用户完成
            SecurityContextHolder.getContext().setAuthentication(authentication);
            filterChain.doFilter(request,response);  // 放行的意思
        }else{ // 登录认证失败了authentication没有，为非法登录
            ResponseUtil.out(null, GlobalResultClass.build(null, ResultStatusEnum.PERMISSION));
        }
    }

    /**
     * // 从请求头中获取对象
     * @return
     */
    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = request.getHeader("token");
//        得到请求头中的token
        // token不为空
        if(!StringUtils.isEmpty(token)){
            log.info("token令牌：{}",token);
            String username = JwtHelper.getUsername(token);
            log.info("用户名：{}",username);
            // usename不为空 返回返回封装的对象
            if(!StringUtils.isEmpty(username)){
                // 通过用户名获取redis中的权限是数据
                String authorities =(String) redisTemplate.opsForValue().get(username);
                log.info("redisTemplate认证对象：{}",authorities);
                if(!StringUtils.isEmpty(authorities)){
                    log.info("authorities:{}",authorities);
                    //把从redis获取的权限数据的字符串转化为要求的集合类型（将json字符串数据还原称List）
                    // 权限数据 authorString不为空
                    // JSON转化为Map格式
                    List<Map> maps = JSON.parseArray(authorities, Map.class);
                    log.info("权限map：{}",maps);
                    // 定义一个空集合接收所需类型的权限数据
                    List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();

                    for (Map map : maps) {
                        simpleGrantedAuthorities.add(new SimpleGrantedAuthority((String)map.get("authority")));
                    }

                    return new UsernamePasswordAuthenticationToken(username, null,simpleGrantedAuthorities);
                }else{
                    return new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList());
                }
            }
        }
        return null;
    }
}
